/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

// Created on 16.11.2005 by RST.
// $Id: GameItems.java,v 1.4 2006/01/21 21:53:32 salomo Exp $
using System;
using Defines = Suake2.UI.Defines;
using Com = Suake2.UI.qcommon.Com;
using Lib = Suake2.UI.util.Lib;
using Math3D = Suake2.UI.util.Math3D;
namespace Suake2.UI.game
{
	
	
	public class GameItems
	{
		public class AnonymousClassEntThinkAdapter:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "do_respawn";
				}
				
			}
			public override bool think(edict_t ent)
			{
				if (ent.team != null)
				{
					edict_t master;
					int count;
					int choice = 0;
					
					master = ent.teammaster;
					
					// count the depth
					for (count = 0, ent = master; ent != null; ent = ent.chain, count++)
						;
					
					choice = Lib.rand() % count;
					
					for (count = 0, ent = master; count < choice; ent = ent.chain, count++)
						;
				}
				
				ent.svflags &= ~ Defines.SVF_NOCLIENT;
				ent.solid = Defines.SOLID_TRIGGER;
				GameBase.gi.linkentity(ent);
				
				// send an effect
				ent.s.event_Renamed = Defines.EV_ITEM_RESPAWN;
				
				return false;
			}
		}
		public class AnonymousClassEntInteractAdapter:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_pack";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				
				gitem_t item;
				int index;
				
				if (other.client.pers.max_bullets < 300)
					other.client.pers.max_bullets = 300;
				if (other.client.pers.max_shells < 200)
					other.client.pers.max_shells = 200;
				if (other.client.pers.max_rockets < 100)
					other.client.pers.max_rockets = 100;
				if (other.client.pers.max_grenades < 100)
					other.client.pers.max_grenades = 100;
				if (other.client.pers.max_cells < 300)
					other.client.pers.max_cells = 300;
				if (other.client.pers.max_slugs < 100)
					other.client.pers.max_slugs = 100;
				
				item = Suake2.UI.game.GameItems.FindItem("Bullets");
				if (item != null)
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
					other.client.pers.inventory[index] += item.quantity;
					if (other.client.pers.inventory[index] > other.client.pers.max_bullets)
						other.client.pers.inventory[index] = other.client.pers.max_bullets;
				}
				
				item = Suake2.UI.game.GameItems.FindItem("Shells");
				if (item != null)
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
					other.client.pers.inventory[index] += item.quantity;
					if (other.client.pers.inventory[index] > other.client.pers.max_shells)
						other.client.pers.inventory[index] = other.client.pers.max_shells;
				}
				
				item = Suake2.UI.game.GameItems.FindItem("Cells");
				if (item != null)
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
					other.client.pers.inventory[index] += item.quantity;
					if (other.client.pers.inventory[index] > other.client.pers.max_cells)
						other.client.pers.inventory[index] = other.client.pers.max_cells;
				}
				
				item = Suake2.UI.game.GameItems.FindItem("Grenades");
				if (item != null)
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
					other.client.pers.inventory[index] += item.quantity;
					if (other.client.pers.inventory[index] > other.client.pers.max_grenades)
						other.client.pers.inventory[index] = other.client.pers.max_grenades;
				}
				
				item = Suake2.UI.game.GameItems.FindItem("Rockets");
				if (item != null)
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
					other.client.pers.inventory[index] += item.quantity;
					if (other.client.pers.inventory[index] > other.client.pers.max_rockets)
						other.client.pers.inventory[index] = other.client.pers.max_rockets;
				}
				
				item = Suake2.UI.game.GameItems.FindItem("Slugs");
				if (item != null)
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
					other.client.pers.inventory[index] += item.quantity;
					if (other.client.pers.inventory[index] > other.client.pers.max_slugs)
						other.client.pers.inventory[index] = other.client.pers.max_slugs;
				}
				
				if (0 == (ent.spawnflags & Defines.DROPPED_ITEM) && (GameBase.deathmatch.value_Renamed != 0))
					jake2.game.GameItems.SetRespawn(ent, ent.item.quantity);
				
				return true;
			}
		}
		public class AnonymousClassEntInteractAdapter1:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_health";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				
				if (0 == (ent.style & Defines.HEALTH_IGNORE_MAX))
					if (other.health >= other.max_health)
						return false;
				
				other.health += ent.count;
				
				if (0 == (ent.style & Defines.HEALTH_IGNORE_MAX))
				{
					if (other.health > other.max_health)
						other.health = other.max_health;
				}
				
				if (0 != (ent.style & Defines.HEALTH_TIMED))
				{
					ent.think = GameUtil.MegaHealth_think;
					ent.nextthink = GameBase.level.time + 5f;
					ent.owner = other;
					ent.flags |= Defines.FL_RESPAWN;
					ent.svflags |= Defines.SVF_NOCLIENT;
					ent.solid = Defines.SOLID_NOT;
				}
				else
				{
					if (!((ent.spawnflags & Defines.DROPPED_ITEM) != 0) && (GameBase.deathmatch.value_Renamed != 0))
						jake2.game.GameItems.SetRespawn(ent, 30);
				}
				
				return true;
			}
		}
		public class AnonymousClassEntTouchAdapter:EntTouchAdapter
		{
			override public System.String ID
			{
				get
				{
					return "touch_item";
				}
				
			}
			public override void  touch(edict_t ent, edict_t other, cplane_t plane, csurface_t surf)
			{
				bool taken;
				
				if (ent.classname.Equals("item_breather"))
					taken = false;
				
				if (other.client == null)
					return ;
				if (other.health < 1)
					return ; // dead people can't pickup
				if (ent.item.pickup == null)
					return ; // not a grabbable item?
				
				taken = ent.item.pickup.interact(ent, other);
				
				if (taken)
				{
					// flash the screen
					other.client.bonus_alpha = 0.25f;
					
					// show icon and name on status bar
					other.client.ps.stats[Defines.STAT_PICKUP_ICON] = (short) GameBase.gi.imageindex(ent.item.icon);
					other.client.ps.stats[Defines.STAT_PICKUP_STRING] = (short) (Defines.CS_ITEMS + jake2.game.GameItems.ITEM_INDEX(ent.item));
					other.client.pickup_msg_time = GameBase.level.time + 3.0f;
					
					// change selected item
					if (ent.item.use != null)
						other.client.pers.selected_item = other.client.ps.stats[Defines.STAT_SELECTED_ITEM] = (short) jake2.game.GameItems.ITEM_INDEX(ent.item);
					
					if (ent.item.pickup == jake2.game.GameItems.Pickup_Health)
					{
						if (ent.count == 2)
							GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/s_health.wav"), 1, Defines.ATTN_NORM, 0);
						else if (ent.count == 10)
							GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/n_health.wav"), 1, Defines.ATTN_NORM, 0);
						else if (ent.count == 25)
							GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/l_health.wav"), 1, Defines.ATTN_NORM, 0);
						// (ent.count == 100)
						else
							GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/m_health.wav"), 1, Defines.ATTN_NORM, 0);
					}
					else if (ent.item.pickup_sound != null)
					{
						GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex(ent.item.pickup_sound), 1, Defines.ATTN_NORM, 0);
					}
				}
				
				if (0 == (ent.spawnflags & Defines.ITEM_TARGETS_USED))
				{
					GameUtil.G_UseTargets(ent, other);
					ent.spawnflags |= Defines.ITEM_TARGETS_USED;
				}
				
				if (!taken)
					return ;
				
				Com.dprintln("Picked up:" + ent.classname);
				
				if (!((GameBase.coop.value_Renamed != 0) && (ent.item.flags & Defines.IT_STAY_COOP) != 0) || 0 != (ent.spawnflags & (Defines.DROPPED_ITEM | Defines.DROPPED_PLAYER_ITEM)))
				{
					if ((ent.flags & Defines.FL_RESPAWN) != 0)
						ent.flags &= ~ Defines.FL_RESPAWN;
					else
						GameUtil.G_FreeEdict(ent);
				}
			}
		}
		public class AnonymousClassEntTouchAdapter1:EntTouchAdapter
		{
			override public System.String ID
			{
				get
				{
					return "drop_temp_touch";
				}
				
			}
			public override void  touch(edict_t ent, edict_t other, cplane_t plane, csurface_t surf)
			{
				if (other == ent.owner)
					return ;
				
				jake2.game.GameItems.Touch_Item_Renamed_Field.touch(ent, other, plane, surf);
			}
		}
		public class AnonymousClassEntThinkAdapter1:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "drop_make_touchable";
				}
				
			}
			public override bool think(edict_t ent)
			{
				ent.touch = Suake2.UI.game.GameItems.Touch_Item_Renamed_Field;
				if (GameBase.deathmatch.value_Renamed != 0)
				{
					ent.nextthink = GameBase.level.time + 29;
					ent.think = GameUtil.G_FreeEdictA;
				}
				return false;
			}
		}
		public class AnonymousClassItemUseAdapter:ItemUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_quad";
				}
				
			}
			public override void  use(edict_t ent, gitem_t item)
			{
				int timeout;
				
				ent.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(item)]--;
				GameUtil.ValidateSelectedItem(ent);
				
				if (jake2.game.GameItems.quad_drop_timeout_hack != 0)
				{
					timeout = Suake2.UI.game.GameItems.quad_drop_timeout_hack;
					jake2.game.GameItems.quad_drop_timeout_hack = 0;
				}
				else
				{
					timeout = 300;
				}
				
				if (ent.client.quad_framenum > GameBase.level.framenum)
					ent.client.quad_framenum += timeout;
				else
					ent.client.quad_framenum = GameBase.level.framenum + timeout;
				
				GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/damage.wav"), 1, Defines.ATTN_NORM, 0);
			}
		}
		public class AnonymousClassItemUseAdapter1:ItemUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_invulnerability";
				}
				
			}
			public override void  use(edict_t ent, gitem_t item)
			{
				ent.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(item)]--;
				GameUtil.ValidateSelectedItem(ent);
				
				if (ent.client.invincible_framenum > GameBase.level.framenum)
					ent.client.invincible_framenum += 300;
				else
					ent.client.invincible_framenum = GameBase.level.framenum + 300;
				
				GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/protect.wav"), 1, Defines.ATTN_NORM, 0);
			}
		}
		public class AnonymousClassItemUseAdapter2:ItemUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_breather";
				}
				
			}
			public override void  use(edict_t ent, gitem_t item)
			{
				ent.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(item)]--;
				
				GameUtil.ValidateSelectedItem(ent);
				
				if (ent.client.breather_framenum > GameBase.level.framenum)
					ent.client.breather_framenum += 300;
				else
					ent.client.breather_framenum = GameBase.level.framenum + 300;
				
				GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/damage.wav"), 1, Defines.ATTN_NORM, 0);
			}
		}
		public class AnonymousClassItemUseAdapter3:ItemUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_envirosuit";
				}
				
			}
			public override void  use(edict_t ent, gitem_t item)
			{
				ent.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(item)]--;
				GameUtil.ValidateSelectedItem(ent);
				
				if (ent.client.enviro_framenum > GameBase.level.framenum)
					ent.client.enviro_framenum += 300;
				else
					ent.client.enviro_framenum = GameBase.level.framenum + 300;
				
				GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/damage.wav"), 1, Defines.ATTN_NORM, 0);
			}
		}
		public class AnonymousClassItemUseAdapter4:ItemUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_silencer";
				}
				
			}
			public override void  use(edict_t ent, gitem_t item)
			{
				
				ent.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(item)]--;
				GameUtil.ValidateSelectedItem(ent);
				ent.client.silencer_shots += 30;
				
				GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/damage.wav"), 1, Defines.ATTN_NORM, 0);
			}
		}
		public class AnonymousClassEntInteractAdapter2:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_key";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				if (GameBase.coop.value_Renamed != 0)
				{
					if (Lib.strcmp(ent.classname, "key_power_cube") == 0)
					{
						if ((other.client.pers.power_cubes & ((ent.spawnflags & 0x0000ff00) >> 8)) != 0)
							return false;
						other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)]++;
						other.client.pers.power_cubes |= ((ent.spawnflags & 0x0000ff00) >> 8);
					}
					else
					{
						if (other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)] != 0)
							return false;
						other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)] = 1;
					}
					return true;
				}
				other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)]++;
				return true;
			}
		}
		public class AnonymousClassEntInteractAdapter3:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_ammo";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				int oldcount;
				int count;
				bool weapon;
				
				weapon = (ent.item.flags & Defines.IT_WEAPON) != 0;
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				if ((weapon) && ((int) GameBase.dmflags.value_Renamed & Defines.DF_INFINITE_AMMO) != 0)
					count = 1000;
				else if (ent.count != 0)
					count = ent.count;
				else
					count = ent.item.quantity;
				
				oldcount = other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)];
				
				if (!jake2.game.GameItems.Add_Ammo(other, ent.item, count))
					return false;
				
				if (weapon && 0 == oldcount)
				{
					if (other.client.pers.weapon != ent.item && (0 == GameBase.deathmatch.value_Renamed || other.client.pers.weapon == jake2.game.GameItems.FindItem("blaster")))
						other.client.newweapon = ent.item;
				}
				
				if (0 == (ent.spawnflags & (Defines.DROPPED_ITEM | Defines.DROPPED_PLAYER_ITEM)) && (GameBase.deathmatch.value_Renamed != 0))
					jake2.game.GameItems.SetRespawn(ent, 30);
				return true;
			}
		}
		public class AnonymousClassEntInteractAdapter4:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_armor";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				int old_armor_index;
				gitem_armor_t oldinfo;
				gitem_armor_t newinfo;
				int newcount;
				float salvage;
				int salvagecount;
				
				// get info on new armor
				newinfo = (gitem_armor_t) ent.item.info;
				
				old_armor_index = Suake2.UI.game.GameItems.ArmorIndex(other);
				
				// handle armor shards specially
				if (ent.item.tag == Defines.ARMOR_SHARD)
				{
					if (0 == old_armor_index)
						other.client.pers.inventory[jake2.game.GameItems.jacket_armor_index] = 2;
					else
						other.client.pers.inventory[old_armor_index] += 2;
				}
				// if player has no armor, just use it
				else if (0 == old_armor_index)
				{
					other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)] = newinfo.base_count;
				}
				// use the better armor
				else
				{
					// get info on old armor
					if (old_armor_index == jake2.game.GameItems.jacket_armor_index)
						oldinfo = Suake2.UI.game.GameItems.jacketarmor_info;
					else if (old_armor_index == jake2.game.GameItems.combat_armor_index)
						oldinfo = Suake2.UI.game.GameItems.combatarmor_info;
					// (old_armor_index == body_armor_index)
					else
						oldinfo = Suake2.UI.game.GameItems.bodyarmor_info;
					
					if (newinfo.normal_protection > oldinfo.normal_protection)
					{
						// calc new armor values
						salvage = oldinfo.normal_protection / newinfo.normal_protection;
						//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
						salvagecount = (int) salvage * other.client.pers.inventory[old_armor_index];
						newcount = newinfo.base_count + salvagecount;
						if (newcount > newinfo.max_count)
							newcount = newinfo.max_count;
						
						// zero count of old armor so it goes away
						other.client.pers.inventory[old_armor_index] = 0;
						
						// change armor to new item with computed value
						other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)] = newcount;
					}
					else
					{
						// calc new armor values
						salvage = newinfo.normal_protection / oldinfo.normal_protection;
						//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
						salvagecount = (int) salvage * newinfo.base_count;
						newcount = other.client.pers.inventory[old_armor_index] + salvagecount;
						if (newcount > oldinfo.max_count)
							newcount = oldinfo.max_count;
						
						// if we're already maxed out then we don't need the new
						// armor
						if (other.client.pers.inventory[old_armor_index] >= newcount)
							return false;
						
						// update current armor value
						other.client.pers.inventory[old_armor_index] = newcount;
					}
				}
				
				if (0 == (ent.spawnflags & Defines.DROPPED_ITEM) && (GameBase.deathmatch.value_Renamed != 0))
					jake2.game.GameItems.SetRespawn(ent, 20);
				
				return true;
			}
		}
		public class AnonymousClassEntInteractAdapter5:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_powerarmor";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				
				int quantity;
				
				quantity = other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)];
				
				other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)]++;
				
				if (GameBase.deathmatch.value_Renamed != 0)
				{
					if (0 == (ent.spawnflags & Defines.DROPPED_ITEM))
						jake2.game.GameItems.SetRespawn(ent, ent.item.quantity);
					// auto-use for DM only if we didn't already have one
					if (0 == quantity)
						ent.item.use.use(other, ent.item);
				}
				return true;
			}
		}
		public class AnonymousClassEntInteractAdapter6:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_powerup";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				int quantity;
				
				quantity = other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)];
				if ((GameBase.skill.value_Renamed == 1 && quantity >= 2) || (GameBase.skill.value_Renamed >= 2 && quantity >= 1))
					return false;
				
				if ((GameBase.coop.value_Renamed != 0) && (ent.item.flags & Defines.IT_STAY_COOP) != 0 && (quantity > 0))
					return false;
				
				other.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(ent.item)]++;
				
				if (GameBase.deathmatch.value_Renamed != 0)
				{
					if (0 == (ent.spawnflags & Defines.DROPPED_ITEM))
						jake2.game.GameItems.SetRespawn(ent, ent.item.quantity);
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					if (((int) GameBase.dmflags.value_Renamed & Defines.DF_INSTANT_ITEMS) != 0 || ((ent.item.use == jake2.game.GameItems.Use_Quad) && 0 != (ent.spawnflags & Defines.DROPPED_PLAYER_ITEM)))
					{
						if ((ent.item.use == jake2.game.GameItems.Use_Quad) && 0 != (ent.spawnflags & Defines.DROPPED_PLAYER_ITEM))
						{
							//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
							jake2.game.GameItems.quad_drop_timeout_hack = (int) ((ent.nextthink - GameBase.level.time) / Defines.FRAMETIME);
						}
						
						ent.item.use.use(other, ent.item);
					}
				}
				
				return true;
			}
		}
		public class AnonymousClassEntInteractAdapter7:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_adrenaline";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				if (GameBase.deathmatch.value_Renamed == 0)
					other.max_health += 1;
				
				if (other.health < other.max_health)
					other.health = other.max_health;
				
				if (0 == (ent.spawnflags & Defines.DROPPED_ITEM) && (GameBase.deathmatch.value_Renamed != 0))
					jake2.game.GameItems.SetRespawn(ent, ent.item.quantity);
				
				return true;
			}
		}
		public class AnonymousClassEntInteractAdapter8:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_ancienthead";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				other.max_health += 2;
				
				if (0 == (ent.spawnflags & Defines.DROPPED_ITEM) && (GameBase.deathmatch.value_Renamed != 0))
					jake2.game.GameItems.SetRespawn(ent, ent.item.quantity);
				
				return true;
			}
		}
		public class AnonymousClassEntInteractAdapter9:EntInteractAdapter
		{
			override public System.String ID
			{
				get
				{
					return "pickup_bandolier";
				}
				
			}
			public override bool interact(edict_t ent, edict_t other)
			{
				gitem_t item;
				int index;
				
				if (other.client.pers.max_bullets < 250)
					other.client.pers.max_bullets = 250;
				if (other.client.pers.max_shells < 150)
					other.client.pers.max_shells = 150;
				if (other.client.pers.max_cells < 250)
					other.client.pers.max_cells = 250;
				if (other.client.pers.max_slugs < 75)
					other.client.pers.max_slugs = 75;
				
				item = Suake2.UI.game.GameItems.FindItem("Bullets");
				if (item != null)
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
					other.client.pers.inventory[index] += item.quantity;
					if (other.client.pers.inventory[index] > other.client.pers.max_bullets)
						other.client.pers.inventory[index] = other.client.pers.max_bullets;
				}
				
				item = Suake2.UI.game.GameItems.FindItem("Shells");
				if (item != null)
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
					other.client.pers.inventory[index] += item.quantity;
					if (other.client.pers.inventory[index] > other.client.pers.max_shells)
						other.client.pers.inventory[index] = other.client.pers.max_shells;
				}
				
				if (0 == (ent.spawnflags & Defines.DROPPED_ITEM) && (GameBase.deathmatch.value_Renamed != 0))
					jake2.game.GameItems.SetRespawn(ent, ent.item.quantity);
				
				return true;
			}
		}
		public class AnonymousClassItemDropAdapter:ItemDropAdapter
		{
			override public System.String ID
			{
				get
				{
					return "drop_ammo";
				}
				
			}
			public override void  drop(edict_t ent, gitem_t item)
			{
				edict_t dropped;
				int index;
				
				index = Suake2.UI.game.GameItems.ITEM_INDEX(item);
				dropped = Suake2.UI.game.GameItems.Drop_Item(ent, item);
				if (ent.client.pers.inventory[index] >= item.quantity)
					dropped.count = item.quantity;
				else
					dropped.count = ent.client.pers.inventory[index];
				
				if (ent.client.pers.weapon != null && ent.client.pers.weapon.tag == Defines.AMMO_GRENADES && item.tag == Defines.AMMO_GRENADES && ent.client.pers.inventory[index] - dropped.count <= 0)
				{
					GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "Can't drop current weapon\n");
					GameUtil.G_FreeEdict(dropped);
					return ;
				}
				
				ent.client.pers.inventory[index] -= dropped.count;
				Cmd.ValidateSelectedItem(ent);
			}
		}
		public class AnonymousClassItemDropAdapter1:ItemDropAdapter
		{
			override public System.String ID
			{
				get
				{
					return "drop_general";
				}
				
			}
			public override void  drop(edict_t ent, gitem_t item)
			{
				jake2.game.GameItems.Drop_Item(ent, item);
				ent.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(item)]--;
				Cmd.ValidateSelectedItem(ent);
			}
		}
		public class AnonymousClassItemDropAdapter2:ItemDropAdapter
		{
			override public System.String ID
			{
				get
				{
					return "drop_powerarmor";
				}
				
			}
			public override void  drop(edict_t ent, gitem_t item)
			{
				if (0 != (ent.flags & Defines.FL_POWER_ARMOR) && (ent.client.pers.inventory[jake2.game.GameItems.ITEM_INDEX(item)] == 1))
					jake2.game.GameItems.Use_PowerArmor.use(ent, item);
				jake2.game.GameItems.Drop_General.drop(ent, item);
			}
		}
		public class AnonymousClassEntThinkAdapter2:EntThinkAdapter
		{
			override public System.String ID
			{
				get
				{
					return "drop_to_floor";
				}
				
			}
			public override bool think(edict_t ent)
			{
				trace_t tr;
				float[] dest = new float[]{0, 0, 0};
				
				//float v[];
				
				//v = Lib.tv(-15, -15, -15);
				//Math3D.VectorCopy(v, ent.mins);
				ent.mins[0] = ent.mins[1] = ent.mins[2] = - 15;
				//v = Lib.tv(15, 15, 15);
				//Math3D.VectorCopy(v, ent.maxs);
				ent.maxs[0] = ent.maxs[1] = ent.maxs[2] = 15;
				
				if (ent.model != null)
					GameBase.gi.setmodel(ent, ent.model);
				else
					GameBase.gi.setmodel(ent, ent.item.world_model);
				ent.solid = Defines.SOLID_TRIGGER;
				ent.movetype = Defines.MOVETYPE_TOSS;
				ent.touch = Suake2.UI.game.GameItems.Touch_Item_Renamed_Field;
				
				float[] v = new float[]{0, 0, - 128};
				Math3D.VectorAdd(ent.s.origin, v, dest);
				
				tr = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, dest, ent, Defines.MASK_SOLID);
				if (tr.startsolid)
				{
					GameBase.gi.dprintf("droptofloor: " + ent.classname + " startsolid at " + Lib.vtos(ent.s.origin) + "\n");
					GameUtil.G_FreeEdict(ent);
					return true;
				}
				
				Math3D.VectorCopy(tr.endpos, ent.s.origin);
				
				if (ent.team != null)
				{
					ent.flags &= ~ Defines.FL_TEAMSLAVE;
					ent.chain = ent.teamchain;
					ent.teamchain = null;
					
					ent.svflags |= Defines.SVF_NOCLIENT;
					ent.solid = Defines.SOLID_NOT;
					if (ent == ent.teammaster)
					{
						ent.nextthink = GameBase.level.time + Defines.FRAMETIME;
						ent.think = Suake2.UI.game.GameItems.DoRespawn;
					}
				}
				
				if ((ent.spawnflags & Defines.ITEM_NO_TOUCH) != 0)
				{
					ent.solid = Defines.SOLID_BBOX;
					ent.touch = null;
					ent.s.effects &= ~ Defines.EF_ROTATE;
					ent.s.renderfx &= ~ Defines.RF_GLOW;
				}
				
				if ((ent.spawnflags & Defines.ITEM_TRIGGER_SPAWN) != 0)
				{
					ent.svflags |= Defines.SVF_NOCLIENT;
					ent.solid = Defines.SOLID_NOT;
					ent.use = Suake2.UI.game.GameItems.Use_Item_Renamed_Field;
				}
				
				GameBase.gi.linkentity(ent);
				return true;
			}
		}
		public class AnonymousClassItemUseAdapter5:ItemUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_powerarmor";
				}
				
			}
			public override void  use(edict_t ent, gitem_t item)
			{
				int index;
				
				if ((ent.flags & Defines.FL_POWER_ARMOR) != 0)
				{
					ent.flags &= ~ Defines.FL_POWER_ARMOR;
					GameBase.gi.sound(ent, Defines.CHAN_AUTO, GameBase.gi.soundindex("misc/power2.wav"), 1, Defines.ATTN_NORM, 0);
				}
				else
				{
					index = Suake2.UI.game.GameItems.ITEM_INDEX(jake2.game.GameItems.FindItem("cells"));
					if (0 == ent.client.pers.inventory[index])
					{
						GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "No cells for power armor.\n");
						return ;
					}
					ent.flags |= Defines.FL_POWER_ARMOR;
					GameBase.gi.sound(ent, Defines.CHAN_AUTO, GameBase.gi.soundindex("misc/power1.wav"), 1, Defines.ATTN_NORM, 0);
				}
			}
		}
		public class AnonymousClassEntUseAdapter:EntUseAdapter
		{
			override public System.String ID
			{
				get
				{
					return "use_item";
				}
				
			}
			public override void  use(edict_t ent, edict_t other, edict_t activator)
			{
				ent.svflags &= ~ Defines.SVF_NOCLIENT;
				ent.use = null;
				
				if ((ent.spawnflags & Defines.ITEM_NO_TOUCH) != 0)
				{
					ent.solid = Defines.SOLID_BBOX;
					ent.touch = null;
				}
				else
				{
					ent.solid = Defines.SOLID_TRIGGER;
					ent.touch = Suake2.UI.game.GameItems.Touch_Item_Renamed_Field;
				}
				
				GameBase.gi.linkentity(ent);
			}
		}
		
		//UPGRADE_NOTE: The initialization of  'jacketarmor_info' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static gitem_armor_t jacketarmor_info;
		//UPGRADE_NOTE: The initialization of  'combatarmor_info' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static gitem_armor_t combatarmor_info;
		//UPGRADE_NOTE: The initialization of  'bodyarmor_info' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static gitem_armor_t bodyarmor_info;
		internal static int quad_drop_timeout_hack = 0;
		internal static int jacket_armor_index;
		internal static int combat_armor_index;
		internal static int body_armor_index;
		internal static int power_screen_index;
		internal static int power_shield_index;
		
		//UPGRADE_NOTE: The initialization of  'DoRespawn' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter DoRespawn;
		//UPGRADE_NOTE: The initialization of  'Pickup_Pack' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntInteractAdapter Pickup_Pack;
		//UPGRADE_NOTE: Final was removed from the declaration of 'Pickup_Health '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		//UPGRADE_NOTE: The initialization of  'Pickup_Health' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static readonly EntInteractAdapter Pickup_Health;
		//UPGRADE_NOTE: The initialization of  'Touch_Item_Renamed_Field' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntTouchAdapter Touch_Item_Renamed_Field;
		//UPGRADE_NOTE: The initialization of  'drop_temp_touch' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntTouchAdapter drop_temp_touch;
		//UPGRADE_NOTE: The initialization of  'drop_make_touchable' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntThinkAdapter drop_make_touchable;
		//UPGRADE_NOTE: The initialization of  'Use_Quad' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static ItemUseAdapter Use_Quad;
		
		//UPGRADE_NOTE: The initialization of  'Use_Invulnerability' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static ItemUseAdapter Use_Invulnerability;
		//UPGRADE_NOTE: The initialization of  'Use_Breather' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static ItemUseAdapter Use_Breather;
		//UPGRADE_NOTE: The initialization of  'Use_Envirosuit' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static ItemUseAdapter Use_Envirosuit;
		//UPGRADE_NOTE: The initialization of  'Use_Silencer' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static ItemUseAdapter Use_Silencer;
		//UPGRADE_NOTE: The initialization of  'Pickup_Key' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		internal static EntInteractAdapter Pickup_Key;
		//UPGRADE_NOTE: The initialization of  'Pickup_Ammo' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntInteractAdapter Pickup_Ammo;
		//UPGRADE_NOTE: The initialization of  'Pickup_Armor' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntInteractAdapter Pickup_Armor;
		//UPGRADE_NOTE: The initialization of  'Pickup_PowerArmor_Renamed_Field' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntInteractAdapter Pickup_PowerArmor_Renamed_Field;
		//UPGRADE_NOTE: The initialization of  'Pickup_Powerup' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntInteractAdapter Pickup_Powerup;
		//UPGRADE_NOTE: The initialization of  'Pickup_Adrenaline' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntInteractAdapter Pickup_Adrenaline;
		//UPGRADE_NOTE: The initialization of  'Pickup_AncientHead' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntInteractAdapter Pickup_AncientHead;
		//UPGRADE_NOTE: The initialization of  'Pickup_Bandolier' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntInteractAdapter Pickup_Bandolier;
		//UPGRADE_NOTE: The initialization of  'Drop_Ammo' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static ItemDropAdapter Drop_Ammo;
		//UPGRADE_NOTE: The initialization of  'Drop_General' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static ItemDropAdapter Drop_General;
		
		//UPGRADE_NOTE: The initialization of  'Drop_PowerArmor' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static ItemDropAdapter Drop_PowerArmor;
		
		//UPGRADE_NOTE: The initialization of  'droptofloor' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntThinkAdapter droptofloor;
		//UPGRADE_NOTE: The initialization of  'Use_PowerArmor' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static ItemUseAdapter Use_PowerArmor;
		//UPGRADE_NOTE: The initialization of  'Use_Item_Renamed_Field' was moved to static method 'jake2.game.GameItems'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		public static EntUseAdapter Use_Item_Renamed_Field;
		
		/*
		* =============== GetItemByIndex ===============
		*/
		public static gitem_t GetItemByIndex(int index)
		{
			if (index == 0 || index >= GameBase.game.num_items)
				return null;
			
			return GameItemList.itemlist[index];
		}
		
		/*
		* =============== FindItemByClassname
		* 
		* ===============
		*/
		internal static gitem_t FindItemByClassname(System.String classname)
		{
			
			for (int i = 1; i < GameBase.game.num_items; i++)
			{
				gitem_t it = GameItemList.itemlist[i];
				
				if (it.classname == null)
					continue;
				if (it.classname.ToUpper().Equals(classname.ToUpper()))
					return it;
			}
			
			return null;
		}
		
		/*
		* =============== FindItem ===============
		*/
		//geht.
		internal static gitem_t FindItem(System.String pickup_name)
		{
			for (int i = 1; i < GameBase.game.num_items; i++)
			{
				gitem_t it = GameItemList.itemlist[i];
				
				if (it.pickup_name == null)
					continue;
				if (it.pickup_name.ToUpper().Equals(pickup_name.ToUpper()))
					return it;
			}
			Com.Println("Item not found:" + pickup_name);
			return null;
		}
		
		internal static void  SetRespawn(edict_t ent, float delay)
		{
			ent.flags |= Defines.FL_RESPAWN;
			ent.svflags |= Defines.SVF_NOCLIENT;
			ent.solid = Defines.SOLID_NOT;
			ent.nextthink = GameBase.level.time + delay;
			ent.think = DoRespawn;
			GameBase.gi.linkentity(ent);
		}
		
		internal static int ITEM_INDEX(gitem_t item)
		{
			return item.index;
		}
		
		internal static edict_t Drop_Item(edict_t ent, gitem_t item)
		{
			edict_t dropped;
			float[] forward = new float[]{0, 0, 0};
			float[] right = new float[]{0, 0, 0};
			float[] offset = new float[]{0, 0, 0};
			
			dropped = GameUtil.G_Spawn();
			
			dropped.classname = item.classname;
			dropped.item = item;
			dropped.spawnflags = Defines.DROPPED_ITEM;
			dropped.s.effects = item.world_model_flags;
			dropped.s.renderfx = Defines.RF_GLOW;
			Math3D.VectorSet(dropped.mins, - 15, - 15, - 15);
			Math3D.VectorSet(dropped.maxs, 15, 15, 15);
			GameBase.gi.setmodel(dropped, dropped.item.world_model);
			dropped.solid = Defines.SOLID_TRIGGER;
			dropped.movetype = Defines.MOVETYPE_TOSS;
			
			dropped.touch = drop_temp_touch;
			
			dropped.owner = ent;
			
			if (ent.client != null)
			{
				trace_t trace;
				
				Math3D.AngleVectors(ent.client.v_angle, forward, right, null);
				Math3D.VectorSet(offset, 24, 0, - 16);
				Math3D.G_ProjectSource(ent.s.origin, offset, forward, right, dropped.s.origin);
				trace = GameBase.gi.trace(ent.s.origin, dropped.mins, dropped.maxs, dropped.s.origin, ent, Defines.CONTENTS_SOLID);
				Math3D.VectorCopy(trace.endpos, dropped.s.origin);
			}
			else
			{
				Math3D.AngleVectors(ent.s.angles, forward, right, null);
				Math3D.VectorCopy(ent.s.origin, dropped.s.origin);
			}
			
			Math3D.VectorScale(forward, 100, dropped.velocity);
			dropped.velocity[2] = 300;
			
			dropped.think = drop_make_touchable;
			dropped.nextthink = GameBase.level.time + 1;
			
			GameBase.gi.linkentity(dropped);
			
			return dropped;
		}
		
		internal static void  Use_Item(edict_t ent, edict_t other, edict_t activator)
		{
			ent.svflags &= ~ Defines.SVF_NOCLIENT;
			ent.use = null;
			
			if ((ent.spawnflags & Defines.ITEM_NO_TOUCH) != 0)
			{
				ent.solid = Defines.SOLID_BBOX;
				ent.touch = null;
			}
			else
			{
				ent.solid = Defines.SOLID_TRIGGER;
				ent.touch = Touch_Item_Renamed_Field;
			}
			
			GameBase.gi.linkentity(ent);
		}
		
		internal static int PowerArmorType(edict_t ent)
		{
			if (ent.client == null)
				return Defines.POWER_ARMOR_NONE;
			
			if (0 == (ent.flags & Defines.FL_POWER_ARMOR))
				return Defines.POWER_ARMOR_NONE;
			
			if (ent.client.pers.inventory[power_shield_index] > 0)
				return Defines.POWER_ARMOR_SHIELD;
			
			if (ent.client.pers.inventory[power_screen_index] > 0)
				return Defines.POWER_ARMOR_SCREEN;
			
			return Defines.POWER_ARMOR_NONE;
		}
		
		internal static int ArmorIndex(edict_t ent)
		{
			if (ent.client == null)
				return 0;
			
			if (ent.client.pers.inventory[jacket_armor_index] > 0)
				return jacket_armor_index;
			
			if (ent.client.pers.inventory[combat_armor_index] > 0)
				return combat_armor_index;
			
			if (ent.client.pers.inventory[body_armor_index] > 0)
				return body_armor_index;
			
			return 0;
		}
		
		public static bool Pickup_PowerArmor(edict_t ent, edict_t other)
		{
			int quantity;
			
			quantity = other.client.pers.inventory[ITEM_INDEX(ent.item)];
			
			other.client.pers.inventory[ITEM_INDEX(ent.item)]++;
			
			if (GameBase.deathmatch.value_Renamed != 0)
			{
				if (0 == (ent.spawnflags & Defines.DROPPED_ITEM))
					SetRespawn(ent, ent.item.quantity);
				// auto-use for DM only if we didn't already have one
				if (0 == quantity)
					ent.item.use.use(other, ent.item);
			}
			
			return true;
		}
		
		public static bool Add_Ammo(edict_t ent, gitem_t item, int count)
		{
			int index;
			int max;
			
			if (null == ent.client)
				return false;
			
			if (item.tag == Defines.AMMO_BULLETS)
				max = ent.client.pers.max_bullets;
			else if (item.tag == Defines.AMMO_SHELLS)
				max = ent.client.pers.max_shells;
			else if (item.tag == Defines.AMMO_ROCKETS)
				max = ent.client.pers.max_rockets;
			else if (item.tag == Defines.AMMO_GRENADES)
				max = ent.client.pers.max_grenades;
			else if (item.tag == Defines.AMMO_CELLS)
				max = ent.client.pers.max_cells;
			else if (item.tag == Defines.AMMO_SLUGS)
				max = ent.client.pers.max_slugs;
			else
				return false;
			
			index = ITEM_INDEX(item);
			
			if (ent.client.pers.inventory[index] == max)
				return false;
			
			ent.client.pers.inventory[index] += count;
			
			if (ent.client.pers.inventory[index] > max)
				ent.client.pers.inventory[index] = max;
			
			return true;
		}
		
		public static void  InitItems()
		{
			GameBase.game.num_items = GameItemList.itemlist.Length - 1;
		}
		
		/*
		* =============== SetItemNames
		* 
		* Called by worldspawn ===============
		*/
		public static void  SetItemNames()
		{
			int i;
			gitem_t it;
			
			for (i = 1; i < GameBase.game.num_items; i++)
			{
				it = GameItemList.itemlist[i];
				GameBase.gi.configstring(Defines.CS_ITEMS + i, it.pickup_name);
			}
			
			jacket_armor_index = ITEM_INDEX(FindItem("Jacket Armor"));
			combat_armor_index = ITEM_INDEX(FindItem("Combat Armor"));
			body_armor_index = ITEM_INDEX(FindItem("Body Armor"));
			power_screen_index = ITEM_INDEX(FindItem("Power Screen"));
			power_shield_index = ITEM_INDEX(FindItem("Power Shield"));
		}
		
		public static void  SelectNextItem(edict_t ent, int itflags)
		{
			gclient_t cl;
			int i, index;
			gitem_t it;
			
			cl = ent.client;
			
			if (cl.chase_target != null)
			{
				GameChase.ChaseNext(ent);
				return ;
			}
			
			// scan for the next valid one
			for (i = 1; i <= Defines.MAX_ITEMS; i++)
			{
				index = (cl.pers.selected_item + i) % Defines.MAX_ITEMS;
				if (0 == cl.pers.inventory[index])
					continue;
				it = GameItemList.itemlist[index];
				if (it.use == null)
					continue;
				if (0 == (it.flags & itflags))
					continue;
				
				cl.pers.selected_item = index;
				return ;
			}
			
			cl.pers.selected_item = - 1;
		}
		
		public static void  SelectPrevItem(edict_t ent, int itflags)
		{
			gclient_t cl;
			int i, index;
			gitem_t it;
			
			cl = ent.client;
			
			if (cl.chase_target != null)
			{
				GameChase.ChasePrev(ent);
				return ;
			}
			
			// scan for the next valid one
			for (i = 1; i <= Defines.MAX_ITEMS; i++)
			{
				index = (cl.pers.selected_item + Defines.MAX_ITEMS - i) % Defines.MAX_ITEMS;
				if (0 == cl.pers.inventory[index])
					continue;
				it = GameItemList.itemlist[index];
				if (null == it.use)
					continue;
				if (0 == (it.flags & itflags))
					continue;
				
				cl.pers.selected_item = index;
				return ;
			}
			
			cl.pers.selected_item = - 1;
		}
		
		/*
		* =============== PrecacheItem
		* 
		* Precaches all data needed for a given item. This will be called for each
		* item spawned in a level, and for each item in each client's inventory.
		* ===============
		*/
		public static void  PrecacheItem(gitem_t it)
		{
			System.String s;
			System.String data;
			int len;
			gitem_t ammo;
			
			if (it == null)
				return ;
			
			if (it.pickup_sound != null)
				GameBase.gi.soundindex(it.pickup_sound);
			
			if (it.world_model != null)
				GameBase.gi.modelindex(it.world_model);
			
			if (it.view_model != null)
				GameBase.gi.modelindex(it.view_model);
			
			if (it.icon != null)
				GameBase.gi.imageindex(it.icon);
			
			// parse everything for its ammo
			if (it.ammo != null && it.ammo.Length != 0)
			{
				ammo = FindItem(it.ammo);
				if (ammo != it)
					PrecacheItem(ammo);
			}
			
			// parse the space seperated precache string for other items
			s = it.precaches;
			if (s == null || s.Length != 0)
				return ;
			
			SupportClass.Tokenizer tk = new SupportClass.Tokenizer(s);
			
			while (tk.HasMoreTokens())
			{
				data = tk.NextToken();
				
				len = data.Length;
				
				if (len >= Defines.MAX_QPATH || len < 5)
					GameBase.gi.error("PrecacheItem: it.classname has bad precache string: " + s);
				
				// determine type based on extension
				if (data.EndsWith("md2"))
					GameBase.gi.modelindex(data);
				else if (data.EndsWith("sp2"))
					GameBase.gi.modelindex(data);
				else if (data.EndsWith("wav"))
					GameBase.gi.soundindex(data);
				else if (data.EndsWith("pcx"))
					GameBase.gi.imageindex(data);
				else
					GameBase.gi.error("PrecacheItem: bad precache string: " + data);
			}
		}
		
		/*
		* ============ SpawnItem
		* 
		* Sets the clipping size and plants the object on the floor.
		* 
		* Items can't be immediately dropped to floor, because they might be on an
		* entity that hasn't spawned yet. ============
		*/
		public static void  SpawnItem(edict_t ent, gitem_t item)
		{
			PrecacheItem(item);
			
			if (ent.spawnflags != 0)
			{
				if (Lib.strcmp(ent.classname, "key_power_cube") != 0)
				{
					ent.spawnflags = 0;
					GameBase.gi.dprintf("" + ent.classname + " at " + Lib.vtos(ent.s.origin) + " has invalid spawnflags set\n");
				}
			}
			
			// some items will be prevented in deathmatch
			if (GameBase.deathmatch.value_Renamed != 0)
			{
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				if (((int) GameBase.dmflags.value_Renamed & Defines.DF_NO_ARMOR) != 0)
				{
					if (item.pickup == Pickup_Armor || item.pickup == Pickup_PowerArmor_Renamed_Field)
					{
						GameUtil.G_FreeEdict(ent);
						return ;
					}
				}
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				if (((int) GameBase.dmflags.value_Renamed & Defines.DF_NO_ITEMS) != 0)
				{
					if (item.pickup == Pickup_Powerup)
					{
						GameUtil.G_FreeEdict(ent);
						return ;
					}
				}
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				if (((int) GameBase.dmflags.value_Renamed & Defines.DF_NO_HEALTH) != 0)
				{
					if (item.pickup == Pickup_Health || item.pickup == Pickup_Adrenaline || item.pickup == Pickup_AncientHead)
					{
						GameUtil.G_FreeEdict(ent);
						return ;
					}
				}
				//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
				if (((int) GameBase.dmflags.value_Renamed & Defines.DF_INFINITE_AMMO) != 0)
				{
					if ((item.flags == Defines.IT_AMMO) || (Lib.strcmp(ent.classname, "weapon_bfg") == 0))
					{
						GameUtil.G_FreeEdict(ent);
						return ;
					}
				}
			}
			
			if (GameBase.coop.value_Renamed != 0 && (Lib.strcmp(ent.classname, "key_power_cube") == 0))
			{
				ent.spawnflags |= (1 << (8 + GameBase.level.power_cubes));
				GameBase.level.power_cubes++;
			}
			
			// don't let them drop items that stay in a coop game
			if ((GameBase.coop.value_Renamed != 0) && (item.flags & Defines.IT_STAY_COOP) != 0)
			{
				item.drop = null;
			}
			
			ent.item = item;
			ent.nextthink = GameBase.level.time + 2 * Defines.FRAMETIME;
			// items start after other solids
			ent.think = droptofloor;
			ent.s.effects = item.world_model_flags;
			ent.s.renderfx = Defines.RF_GLOW;
			
			if (ent.model != null)
				GameBase.gi.modelindex(ent.model);
		}
		
		/*
		* QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16)
		*/
		public static void  SP_item_health(edict_t self)
		{
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			if (GameBase.deathmatch.value_Renamed != 0 && ((int) GameBase.dmflags.value_Renamed & Defines.DF_NO_HEALTH) != 0)
			{
				GameUtil.G_FreeEdict(self);
			}
			
			self.model = "models/items/healing/medium/tris.md2";
			self.count = 10;
			SpawnItem(self, FindItem("Health"));
			GameBase.gi.soundindex("items/n_health.wav");
		}
		
		/*
		* QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16)
		*/
		internal static void  SP_item_health_small(edict_t self)
		{
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			if (GameBase.deathmatch.value_Renamed != 0 && ((int) GameBase.dmflags.value_Renamed & Defines.DF_NO_HEALTH) != 0)
			{
				GameUtil.G_FreeEdict(self);
				return ;
			}
			
			self.model = "models/items/healing/stimpack/tris.md2";
			self.count = 2;
			SpawnItem(self, FindItem("Health"));
			self.style = Defines.HEALTH_IGNORE_MAX;
			GameBase.gi.soundindex("items/s_health.wav");
		}
		
		/*
		* QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16)
		*/
		internal static void  SP_item_health_large(edict_t self)
		{
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			if (GameBase.deathmatch.value_Renamed != 0 && ((int) GameBase.dmflags.value_Renamed & Defines.DF_NO_HEALTH) != 0)
			{
				GameUtil.G_FreeEdict(self);
				return ;
			}
			
			self.model = "models/items/healing/large/tris.md2";
			self.count = 25;
			SpawnItem(self, FindItem("Health"));
			GameBase.gi.soundindex("items/l_health.wav");
		}
		
		/*
		* QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16)
		*/
		internal static void  SP_item_health_mega(edict_t self)
		{
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			if (GameBase.deathmatch.value_Renamed != 0 && ((int) GameBase.dmflags.value_Renamed & Defines.DF_NO_HEALTH) != 0)
			{
				GameUtil.G_FreeEdict(self);
				return ;
			}
			
			self.model = "models/items/mega_h/tris.md2";
			self.count = 100;
			SpawnItem(self, FindItem("Health"));
			GameBase.gi.soundindex("items/m_health.wav");
			self.style = Defines.HEALTH_IGNORE_MAX | Defines.HEALTH_TIMED;
		}
		
		/*
		* =============== 
		* Touch_Item 
		* ===============
		*/
		public static void  Touch_Item(edict_t ent, edict_t other, cplane_t plane, csurface_t surf)
		{
			bool taken;
			
			// freed edicts have not items.
			if (other.client == null || ent.item == null)
				return ;
			if (other.health < 1)
				return ; // dead people can't pickup
			if (ent.item.pickup == null)
				return ; // not a grabbable item?
			
			taken = ent.item.pickup.interact(ent, other);
			
			if (taken)
			{
				// flash the screen
				other.client.bonus_alpha = 0.25f;
				
				// show icon and name on status bar
				other.client.ps.stats[Defines.STAT_PICKUP_ICON] = (short) GameBase.gi.imageindex(ent.item.icon);
				other.client.ps.stats[Defines.STAT_PICKUP_STRING] = (short) (Defines.CS_ITEMS + ITEM_INDEX(ent.item));
				other.client.pickup_msg_time = GameBase.level.time + 3.0f;
				
				// change selected item
				if (ent.item.use != null)
					other.client.pers.selected_item = other.client.ps.stats[Defines.STAT_SELECTED_ITEM] = (short) ITEM_INDEX(ent.item);
				
				if (ent.item.pickup == Pickup_Health)
				{
					if (ent.count == 2)
						GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/s_health.wav"), 1, Defines.ATTN_NORM, 0);
					else if (ent.count == 10)
						GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/n_health.wav"), 1, Defines.ATTN_NORM, 0);
					else if (ent.count == 25)
						GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/l_health.wav"), 1, Defines.ATTN_NORM, 0);
					// (ent.count == 100)
					else
						GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/m_health.wav"), 1, Defines.ATTN_NORM, 0);
				}
				else if (ent.item.pickup_sound != null)
				{
					GameBase.gi.sound(other, Defines.CHAN_ITEM, GameBase.gi.soundindex(ent.item.pickup_sound), 1, Defines.ATTN_NORM, 0);
				}
			}
			
			if (0 == (ent.spawnflags & Defines.ITEM_TARGETS_USED))
			{
				GameUtil.G_UseTargets(ent, other);
				ent.spawnflags |= Defines.ITEM_TARGETS_USED;
			}
			
			if (!taken)
				return ;
			
			if (!((GameBase.coop.value_Renamed != 0) && (ent.item.flags & Defines.IT_STAY_COOP) != 0) || 0 != (ent.spawnflags & (Defines.DROPPED_ITEM | Defines.DROPPED_PLAYER_ITEM)))
			{
				if ((ent.flags & Defines.FL_RESPAWN) != 0)
					ent.flags &= ~ Defines.FL_RESPAWN;
				else
					GameUtil.G_FreeEdict(ent);
			}
		}
		static GameItems()
		{
			jacketarmor_info = new gitem_armor_t(25, 50, .30f, .00f, Defines.ARMOR_JACKET);
			combatarmor_info = new gitem_armor_t(50, 100, .60f, .30f, Defines.ARMOR_COMBAT);
			bodyarmor_info = new gitem_armor_t(100, 200, .80f, .60f, Defines.ARMOR_BODY);
			DoRespawn = new AnonymousClassEntThinkAdapter();
			Pickup_Pack = new AnonymousClassEntInteractAdapter();
			Pickup_Health = new AnonymousClassEntInteractAdapter1();
			Touch_Item_Renamed_Field = new AnonymousClassEntTouchAdapter();
			drop_temp_touch = new AnonymousClassEntTouchAdapter1();
			drop_make_touchable = new AnonymousClassEntThinkAdapter1();
			Use_Quad = new AnonymousClassItemUseAdapter();
			Use_Invulnerability = new AnonymousClassItemUseAdapter1();
			Use_Breather = new AnonymousClassItemUseAdapter2();
			Use_Envirosuit = new AnonymousClassItemUseAdapter3();
			Use_Silencer = new AnonymousClassItemUseAdapter4();
			Pickup_Key = new AnonymousClassEntInteractAdapter2();
			Pickup_Ammo = new AnonymousClassEntInteractAdapter3();
			Pickup_Armor = new AnonymousClassEntInteractAdapter4();
			Pickup_PowerArmor_Renamed_Field = new AnonymousClassEntInteractAdapter5();
			Pickup_Powerup = new AnonymousClassEntInteractAdapter6();
			Pickup_Adrenaline = new AnonymousClassEntInteractAdapter7();
			Pickup_AncientHead = new AnonymousClassEntInteractAdapter8();
			Pickup_Bandolier = new AnonymousClassEntInteractAdapter9();
			Drop_Ammo = new AnonymousClassItemDropAdapter();
			Drop_General = new AnonymousClassItemDropAdapter1();
			Drop_PowerArmor = new AnonymousClassItemDropAdapter2();
			droptofloor = new AnonymousClassEntThinkAdapter2();
			Use_PowerArmor = new AnonymousClassItemUseAdapter5();
			Use_Item_Renamed_Field = new AnonymousClassEntUseAdapter();
		}
	}
}